import React, { useRef, useEffect } from "react";
import {
    Scene, WebGLRenderer, BoxGeometry, MeshNormalMaterial, Mesh,
    Matrix4, Vector3, PerspectiveCamera, Object3DEventMap, Light, DirectionalLight, MeshPhongMaterial, MeshBasicMaterial,
    CircleGeometry, PlaneGeometry, RingGeometry, ShapeGeometry, Shape,
} from 'three';
import "./css/ResponsiveDesign.css"
import { vs, fs } from './shader/default'

// if (navigator.gpu) {
//     console.log('支持');
// } else {
//     console.log('不支持');
// }

//浏览器请求GPU适配器
const adapter = await navigator.gpu.requestAdapter();
//获取GPU设备对象, 通过GPU设备镀锡device的WebGPU API可以控制GPU的渲染过程
const device = await adapter?.requestDevice() as GPUDevice;


const canvas = document.createElement("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const context = canvas.getContext('webgpu')!;
const format = navigator.gpu.getPreferredCanvasFormat();//颜色数据
context?.configure({
    device: device,//GPU对象
    format: format,//颜色数据
});

// 创建命令编码器
const commandEncoder = device.createCommandEncoder();
// 创建渲染通道对象
const renderPass = commandEncoder.beginRenderPass({
    colorAttachments: [
        {
            //指向用于Canvas画布纹理视图对象(Canvas对应的缓冲区)
            //该渲染管道renderPass输出的像素会存储到Canvas对应的颜色缓冲区
            view: context.getCurrentTexture().createView(),
            storeOp: 'store',//像素数据写入颜色缓冲区
            loadOp: 'clear',//每次渲染前执行清除?
            clearValue: { r: 0.5, g: 0.5, b: 0.5, a: 1.0 },//背景颜色
        }
    ]
});


//加载顶点着色器
const vsM = device.createShaderModule({ code: vs });
const fsM = device.createShaderModule({ code: fs });

// 创建渲染管线
const pipeline = device.createRenderPipeline({
    vertex: {//顶点作色器
        module: vsM,
        entryPoint: 'main',//入口函数
        buffers: [//顶点所有缓冲区模块的设置
            {//其中一个顶点缓冲区的设置
                arrayStride: 3 * 4,//一个顶点数据占用的字节长度(三维 * 4)
                attributes: [{
                    shaderLocation: 0,  //GPU显存是顶点缓冲区标记存储位置
                    format: 'float32x3',//格式: float32x3表示一个顶点数据包含3个3
                    offset: 0           //偏移量?    
                }],
            }
        ]
    },
    fragment: {//片元作色器
        module: fsM,
        entryPoint: 'main',//入口函数
        targets: [{
            format: format
        }],
    },
    primitive: {
        topology: "triangle-list",//绘制三角形
    },
    layout: 'auto',
});



//设置当前需要控制的渲染管线
renderPass.setPipeline(pipeline);


const vertices = new Float32Array([
    0.0, 0.0, 0.0,
    0.5, 0.0, 0.0,
    0.25, 0.5, 0.0,
]);
const verticesBuffer = device.createBuffer({
    //缓冲区字节长度
    size: vertices.byteLength,
    //设置该缓冲区的用途(VERTEX表示用于存储顶点数据)
    usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST
});
device.queue.writeBuffer(verticesBuffer, 0, vertices);
//把缓冲区绑定(此处的0,与shader中location(0)相匹配, 并与pipeline.shaderLocation相同)
renderPass.setVertexBuffer(0, verticesBuffer);




const mm4 = new Float32Array(new Matrix4().makeScale(0.5, 0.5, 0.5).elements);
const mm4Buffer = device.createBuffer({
    size: mm4.byteLength,
    usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
});
device.queue.writeBuffer(mm4Buffer, 0, mm4);
const bindGroup = device.createBindGroup({
    layout: pipeline.getBindGroupLayout(0),
    entries: [
        { binding: 0, resource: { buffer: mm4Buffer } },
    ]
});
renderPass.setBindGroup(0, bindGroup);


const color = new Float32Array([0, 1, 0, 1]);
const colorBuffer = device.createBuffer({
    size: color.byteLength,
    usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
});
device.queue.writeBuffer(colorBuffer, 0, color);
const bindGroup1 = device.createBindGroup({
    layout: pipeline.getBindGroupLayout(1),
    entries: [
        { binding: 0, resource: { buffer: colorBuffer } },
    ]
});
renderPass.setBindGroup(1, bindGroup1);




renderPass.draw(3);
renderPass.end();

//创建命令缓冲区
const commandBuffer = commandEncoder.finish();
//生成GPU指令存入缓冲区
device.queue.submit([commandBuffer]);



let loadIndex = 0;
const RenderStructure = () => {
    const divRef = useRef<HTMLDivElement>(null);
    useEffect(() => {
        const { current } = divRef;
        if (current != null) {
            current.innerHTML = '';
            current.append(canvas);
        }
    }, []);
    return (
        <div ref={divRef}></div>
    );
};

export default RenderStructure;
